{
    "cells": [
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "# Simulation Result Analysor"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "import matplotlib\n",
                "import matplotlib.pyplot as plt\n",
                "import numpy as np\n",
                "import pandas as pd\n",
                "import seaborn as sns\n",
                "from matplotlib.lines import Line2D\n",
                "import matplotlib.patches as mpatches\n",
                "\n",
                "sns.set_style(\"ticks\")\n",
                "font = {\n",
                "    \"font.family\": \"Roboto\",\n",
                "    \"font.size\": 12,\n",
                "}\n",
                "sns.set_style(font)\n",
                "paper_rc = {\n",
                "    \"lines.linewidth\": 3,\n",
                "    \"lines.markersize\": 10,\n",
                "}\n",
                "sns.set_context(\"paper\", font_scale=1.8, rc=paper_rc)\n",
                "current_palette = sns.color_palette()\n",
                "\n",
                "pd.set_option(\"display.max_columns\", None)\n",
                "cmp = sns.color_palette(\"tab10\")\n",
                "color_list = [cmp[7], cmp[1], cmp[2], cmp[4], cmp[-1]]\n",
                "\n",
                "\n",
                "policy_dict = {\"fifo\": \"FIFO\", \"sjf\": \"SJF\", \"qssf\": \"QSSF\", \"tiresias\": \"Tiresias\", \"lucid\": \"Lucid\"}\n",
                "policy_list = list(policy_dict.values())\n",
                "policy_list_lower = list(policy_dict.keys())\n",
                "cluster_list = [\"Venus\", \"Saturn\", \"Philly\"]\n",
                "experiment_list = [\"Venus_Sept\", \"Saturn_Sept\", \"Philly\"]\n",
                "\n",
                "save = True\n",
                "experiment_name = experiment_list[0]\n",
                "log_dir = f\"../log/{experiment_name}\"\n",
                "placer = \"consolidate\"\n",
                "cluster = experiment_name.split(\"_\")[0]\n",
                "\n",
                "jct_avg = pd.read_csv(f\"{log_dir}/jct_avg_{placer}.csv\", index_col=0)\n",
                "que_avg = pd.read_csv(f\"{log_dir}/que_avg_{placer}.csv\", index_col=0)\n",
                "\n",
                "\n",
                "def process_summary(df):\n",
                "    all_df = df.loc[[\"all\"]]\n",
                "    df = df.drop(index=\"all\")\n",
                "    df.sort_values(by=\"fifo_consolidate\", ascending=False, inplace=True)\n",
                "    df = df.head(10)\n",
                "    df = pd.concat([df, all_df])\n",
                "\n",
                "    if \"srtf_consolidate\" in df.columns:\n",
                "        df = df.drop(columns=\"srtf_consolidate\")\n",
                "\n",
                "    # exchange tiresias and lucid\n",
                "    cols = [x + f'_{placer}' for x in policy_list_lower]\n",
                "    # cols[-1], cols[-2] = cols[-2], cols[-1]\n",
                "    df = df.reindex(columns=cols)\n",
                "    return df"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Table 4: Result Summary"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "jct = pd.DataFrame() # Average JCT\n",
                "que = pd.DataFrame() # Average Queuing Delay\n",
                "quetail = pd.DataFrame() # Queuing Delay Quantile\n",
                "\n",
                "for experiment_name in [\"Venus_Sept\"]:\n",
                "    cluster = experiment_name.split('_')[0]\n",
                "    for policy in policy_list:\n",
                "        log = pd.read_csv(f'../log/{experiment_name}/all/{policy.lower()}_consolidate_all_log.csv')\n",
                "        jct.at[policy, cluster] = log['jct'].mean()\n",
                "        que.at[policy, cluster] = log['queue'].mean()\n",
                "        quetail.at[policy, cluster] = log['queue'].quantile(q=0.999)\n",
                "\n",
                "print(\"Average JCT\")\n",
                "print(jct.astype(int))\n",
                "print(\"\\nAverage Queuing Delay\")\n",
                "print(que.astype(int))\n",
                "print(\"\\nQueuing Delay 99.9 Quantile\")\n",
                "print(quetail.astype(int))\n",
                "\n",
                "jct = pd.concat([jct, que, quetail])\n",
                "jct = jct.astype(int)\n",
                "jct.to_csv('result_summary.csv')"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Table 5: Result Summary of Different Scales of Workloads"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "jct = pd.DataFrame()  # Average JCT\n",
                "que = pd.DataFrame()  # Average Queuing Delay\n",
                "\n",
                "for experiment_name in [\"Venus_Sept\"]:\n",
                "    cluster = experiment_name.split(\"_\")[0]\n",
                "    for policy in [\"fifo\", \"tiresias\", \"lucid\"]:\n",
                "        log = pd.read_csv(f\"../log/{experiment_name}/all/{policy.lower()}_consolidate_all_log.csv\")\n",
                "        jct.at[policy, f\"{cluster}(Large)\"] = log[log[\"gpu_num\"] > 8][\"jct\"].mean()\n",
                "        jct.at[policy, f\"{cluster}(Small)\"] = log[log[\"gpu_num\"] <= 8][\"jct\"].mean()\n",
                "        que.at[policy, f\"{cluster}(Large)\"] = log[log[\"gpu_num\"] > 8][\"queue\"].mean()\n",
                "        que.at[policy, f\"{cluster}(Small)\"] = log[log[\"gpu_num\"] <= 8][\"queue\"].mean()\n",
                "\n",
                "print(\"Average JCT\")\n",
                "print(jct.astype(int))\n",
                "print(\"\\nAverage Queuing Delay\")\n",
                "print(que.astype(int))"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Plot Result 8: JCT"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "fig, axs = plt.subplots(ncols=1, nrows=1, constrained_layout=True, figsize=(6, 4))\n",
                "axs = [axs]\n",
                "\n",
                "experiment_list = [\"Venus_Sept\"]\n",
                "placer = \"consolidate\"\n",
                "cluster_list = [\"Venus\"]\n",
                "linestyles = [\"--\", \"-.\", \":\", \"--\", \"-.\", \"-\"]\n",
                "\n",
                "for e in range(0, len(experiment_list)):\n",
                "    for k in range(0, len(policy_list_lower)):\n",
                "        job_ratio = []\n",
                "        time = [2**i for i in range(0, 22)]\n",
                "\n",
                "        log_dir = f\"../log/{experiment_list[e]}/all\"\n",
                "\n",
                "        log = pd.read_csv(f\"{log_dir}/{policy_list_lower[k]}_{placer}_all_log.csv\")\n",
                "\n",
                "        for t in time:\n",
                "            job_ratio.append(len(log[log[\"jct\"] <= t]) / len(log) * 100)\n",
                "\n",
                "        axs[e].plot(time, job_ratio, linestyles[k], alpha=0.9, label=policy_list[k], color=color_list[k])\n",
                "\n",
                "marks = {0: \"a\", 1: \"b\", 2: \"c\"}\n",
                "for e in range(1):\n",
                "    axs[e].set_xscale(\"log\")\n",
                "    axs[e].set_xlabel(f\"{cluster_list[e]}: JCT (s)\")\n",
                "    axs[e].set_ylabel(f\"Fraction of Jobs (%)\")\n",
                "    axs[e].set_xlim(1, time[-1])\n",
                "    axs[e].set_ylim(0, 100)\n",
                "    axs[e].grid(linestyle=\":\")\n",
                "\n",
                "axs[0].annotate(\"Better\", xy=(5, 95), xytext=(20, 70), arrowprops=dict(facecolor=\"black\", width=3.5, headwidth=10))\n",
                "\n",
                "\n",
                "handles, labels = axs[0].get_legend_handles_labels()\n",
                "fig.legend(\n",
                "    handles,\n",
                "    labels,\n",
                "    loc=\"upper center\",\n",
                "    ncol=6,\n",
                "    bbox_to_anchor=(0.54, 1.15),\n",
                "    fancybox=True,\n",
                "    shadow=True,\n",
                "    fontsize=14,\n",
                "    handletextpad=0.5,\n",
                "    columnspacing=1.2,\n",
                ")\n",
                "sns.despine()\n",
                "\n",
                "save = True\n",
                "if save:\n",
                "    fig.savefig(f\"result_cdf_jct.pdf\", bbox_inches=\"tight\")\n"
            ]
        },
        {
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Plot Result 9: Queue Time in each VC"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "from matplotlib.gridspec import GridSpec\n",
                "\n",
                "jct_avg = [None]*3\n",
                "que_avg = [None]*3\n",
                "cluster = [None]*3\n",
                "cmp = sns.color_palette(\"tab10\")\n",
                "def read_file(experiment_name):\n",
                "    log_dir = f\"../log/{experiment_name}\"\n",
                "    placer = \"consolidate\"\n",
                "    cluster = experiment_name.split(\"_\")[0]\n",
                "\n",
                "    jct_avg = pd.read_csv(f\"{log_dir}/jct_avg_{placer}.csv\", index_col=0)\n",
                "    que_avg = pd.read_csv(f\"{log_dir}/que_avg_{placer}.csv\", index_col=0)\n",
                "    jct_avg = process_summary(jct_avg)\n",
                "    que_avg = process_summary(que_avg)\n",
                "    return jct_avg, que_avg, cluster\n",
                "\n",
                "jct_avg[0], que_avg[0], cluster[0] = read_file(experiment_list[0])\n",
                "que_avg[0].drop(['vcLTP', 'vchA3'], inplace=True)\n",
                "\n",
                "grid_params=dict(width_ratios=[6, 6, 1])\n",
                "fig, axs = plt.subplots(ncols=1, nrows=1, constrained_layout=True, figsize=(8, 3))\n",
                "axs = [axs]\n",
                "\n",
                "width = 0.15\n",
                "x = np.arange(1, len(que_avg[0]) + 1)\n",
                "off = width * len(que_avg[0].columns) * 2\n",
                "labels = []\n",
                "for c in que_avg[0].columns:\n",
                "    labels.append(c.split(\"_\")[0])\n",
                "\n",
                "col_num = len(que_avg[0].columns)\n",
                "for i in range(col_num):\n",
                "    offset = i - col_num // 2\n",
                "    p1 = axs[0].bar(\n",
                "        x + offset * width,\n",
                "        que_avg[0].iloc[:, i],\n",
                "        width,\n",
                "        alpha=0.9,\n",
                "        linewidth=0.8,\n",
                "        edgecolor=\"k\",\n",
                "        label=policy_dict[labels[i]],\n",
                "        color=color_list[i]\n",
                "    )\n",
                "\n",
                "ylabel = f\"Average Queuing Time (s)\"\n",
                "axs[0].set_xlabel(f\"VC in {cluster[0]}\")\n",
                "axs[0].set_ylabel(ylabel)\n",
                "# axs[0].set_yscale('log')\n",
                "axs[0].set_xticks(x)\n",
                "axs[0].set_xlim(0.3, 9.7)\n",
                "axs[0].set_ylim(0, 20000)\n",
                "axs[0].set_xticklabels(que_avg[0].index.values, fontsize=13)\n",
                "axs[0].ticklabel_format(axis=\"y\", style=\"sci\", scilimits=(-6, 2), useMathText=True)\n",
                "axs[0].grid(axis=\"y\", linestyle=\":\")\n",
                "axs[0].annotate(\"11\", xy=(0.72, 19999), xytext = (0.9, 18000), arrowprops=dict(facecolor='black', width=2, headwidth=6), fontsize=13)\n",
                "axs[0].annotate(\"8.0\", xy=(1.72, 19999), xytext = (1.9, 18000), arrowprops=dict(facecolor='black', width=2, headwidth=6), fontsize=13)\n",
                "axs[0].annotate(\"7.6\", xy=(2.72, 19999), xytext = (2.9, 18000), arrowprops=dict(facecolor='black', width=2, headwidth=6), fontsize=13)\n",
                "axs[0].annotate(\"2.1\", xy=(3.72, 19999), xytext = (3.9, 18000), arrowprops=dict(facecolor='black', width=2, headwidth=6), fontsize=13)\n",
                "axs[0].annotate(\"5.5\", xy=(8.72, 19999), xytext = (8.9, 18000), arrowprops=dict(facecolor='black', width=2, headwidth=6), fontsize=13)\n",
                "sns.despine()\n",
                "\n",
                "\n",
                "handles, labels = axs[0].get_legend_handles_labels()\n",
                "fig.legend(\n",
                "    handles,\n",
                "    labels,\n",
                "    loc=\"upper center\",\n",
                "    ncol=6,\n",
                "    bbox_to_anchor=(0.54, 1.18),\n",
                "    fancybox=True,\n",
                "    shadow=True,\n",
                "    fontsize=14,\n",
                "    handletextpad=0.5,\n",
                "    columnspacing=1.2\n",
                ")\n",
                "save = True\n",
                "if save:\n",
                "    fig.savefig(f\"result_bar_queue.pdf\", bbox_inches=\"tight\")\n"
            ]
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "Python 3.9.13 ('base')",
            "language": "python",
            "name": "python3"
        },
        "language_info": {
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "file_extension": ".py",
            "mimetype": "text/x-python",
            "name": "python",
            "nbconvert_exporter": "python",
            "pygments_lexer": "ipython3",
            "version": "3.9.13"
        },
        "vscode": {
            "interpreter": {
                "hash": "784914556ea7aafefbdcb0c4fefea2600a01efb6a6b7916d4154dc17a3e6434f"
            }
        }
    },
    "nbformat": 4,
    "nbformat_minor": 4
}
